package net.alche.sdd.servlet.imp;

import net.alche.al.util.AC;
import net.alche.al.util.Far;
import net.alche.fa.biz.iface.FaHttpRequestResp;
import net.alche.sdd.pojo.MultipartFile;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.smartboot.http.common.Cookie;
import org.smartboot.http.server.HttpRequest;
import org.smartboot.http.server.HttpResponse;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import org.smartboot.http.common.enums.HttpStatus;

@SuppressWarnings("all")
public class SddHttpRequestResp extends FaHttpRequestResp {
  public String appPath = "/";
  HttpRequest request;
  HttpResponse response;
  SddHttpSession session = null;
  Map<String, String> pathMap = null;
  String bodyStr = null;

  public String getHttpType() {
    switch (request.getMethod()) {
      case "GET": {
        return "get";
      }
      case "POST": {
        return "post";
      }
      case "DELETE": {
        return "del";
      }
      case "PUT": {
        return "put";
      }
      default: {
        return "*";
      }
    }
  }

  public SddHttpRequestResp(HttpRequest request, HttpResponse response) {
    this.request = request;
    this.response = response;
  }

  public SddHttpRequestResp(HttpRequest request, HttpResponse response, String path) {
    this.request = request;
    this.response = response;
    this.appPath = path;
  }

  public SddHttpSession getSesson() {
    if (session != null) {
      return session;
    }
    Collection<String> names = request.getHeaderNames();
    Cookie[] coks = request.getCookies();
    String cookies = request.getHeader("Cookie");
    String sessionKey = null;
    if (coks != null && coks.length > 0) {
      for (Cookie ck : coks) {
        if (jsSessionName.equals(ck.getName())) {
          sessionKey = ck.getValue();
          break;
        }
      }
    }
    if (sessionKey != null) {
      session = SddHttpSession.getSession(sessionKey);
      if (session != null && !session.isEnable()) {
        session = null;
        SddHttpSession.putSession(sessionKey, null);
      }
    } else {
      sessionKey = AC.system.getUUid();
    }
    if (session == null) {
      session = new SddHttpSession();
      SddHttpSession.putSession(sessionKey, session);
      response.setHeader("Set-Cookie", jsSessionName + "=" + sessionKey + "; Path=" + "/" + "; Secure; HttpOnly");
      // Cookie nk = new Cookie(jsSessionName, sessionKey);
      // response.addCookie(nk);
    }
    return session;
  }

  public void setSessionVal(String key, Object val) {
    getSesson().mp.put(key, val);
  }

  @Override
  public Object getSessionVal(String key) {
    return getSesson().mp.get(key);
  }

  @Override
  public String getParam(String key) {
    return request.getParameter(key);
  }

  @Override
  public Map<String, Object> getParamMap() {
    Map<String, String[]> mp = request.getParameters();
    Map<String, Object> rb = new HashMap<>();
    for (Entry<String, String[]> item : mp.entrySet()) {
      if (item.getValue() != null && item.getValue().length > 0) {
        rb.put(item.getKey(), item.getValue()[0]);
      }
    }
    return rb;
  }

  public String getPathParam(String key) {
    if (pathMap == null)
      return null;
    return pathMap.get(key);
  }

  @Override
  public String[] getParamValues(String key) {
    return request.getParameterValues(key);
  }

  @Override
  public void write(Object obj) throws IOException {
    if (obj == null)
      return;
    response.write(obj.toString().getBytes(AC.file.getUtf8()));
  }

  @Override
  public void writeBytes(byte[] obj) throws IOException {
    response.write(obj);
  }

  @Override
  public String getBodyStr() {
    if (bodyStr != null) {
      return bodyStr;
    }
    try {
      bodyStr = IoUtil.readUtf8(request.getInputStream());
      return bodyStr;
    } catch (Exception e) {
      return null;
    }

  }

  @Override
  public void setContentType(String contextType) {
    response.setContentType(contextType);
  }

  @Override
  public void setPathAiParam(String source, String methodPath) {
    String[] sp = source.split("/");
    String[] sp2 = methodPath.split("/");
    pathMap = new HashMap<>();
    for (int i = 0; i < sp.length && i < sp2.length; i++) {
      if (!sp[i].equals(sp2[i])) {
        String key = sp2[i].substring(1, sp2[i].length() - 1);
        String val = sp[i];
        pathMap.put(key, val);
      }
    }
  }

  public void destroySession() {
    getSesson().invalidate();
  }

  @Override
  public MultipartFile readMultipartFile() {
    return new MultipartFile(request);
  }

  @Override
  public String getIpAddr() {
    return getIPAddress(request);
  }

  @Override
  public String getIpAddrV6() {
    return getIPAddress(request);
  }

  @Override
  public String getHeader(String headKey) {
    return request.getHeader(headKey);
  }

  public void setStatues(int status) {
    if (status == 404) {
      response.setHttpStatus(HttpStatus.NOT_FOUND);
    }
  }

  @Override
  public String getHostName() {
    return request.getRemoteHost();
  }
}
